前言

这一篇综合从百度实时疫情网址爬取数据并用pyecharts显示疫情地图分布。

其中地图分为具体省份疫情地图和中国总体疫情地图。

每一个省份对应一个html地图。

pyecharts map模块链接

实现思路是

  1. 获取数据
  2. 保存为html.txt文件
  3. 解析html.txt,获取需要的数据,并保存为data.json
  4. 分别创建省份疫情地图和中国疫情的方法,填充数据
  5. 运行main.py

遇到的问题

在map_draw.py中,其中具体省份疫情地图是用的pyecharts官网广东地图实例,其中有一个参数Faker.guangdong_city,我们把demo复制到pycharm ctrl+鼠标左键 进入这个参数后,

发现这个参数的数据是这样的:

guangdong_city = [“汕头市”, “汕尾市”, “揭阳市”, “阳江市”, “肇庆市”, “广州市”, “惠州市”]

而我们获取的数据有些是不带市的,所以要进行一下字符串的处理

for each_city in each['subList']:
            city.append(each_city['city'] + "市")
            confirmeds.append(each_city['confirmed'])
            map.to_map_city(city, confirmeds, province, update_tqime)
        if province == '上海' or '北京' or '天津' or '重庆':
            for each_city in each['subList']:
                city.append(each_city['city'])
                confirmeds.append(each_city['confirmed'])
                map.to_map_city(city, confirmeds, province, update_time)

注意需要提前在根目录建好map文件夹,存储具体省份的疫情图。

最终效果

中国总体累计确诊分布图:

img

广东省累计确诊分布图:

img

具体代码实现

data_get.py:

import requests
from lxml import etree
import json
import re


# 获取数据
class Get_data():
    # 抓取数据
    def get_data(self):
        url = 'https://voice.baidu.com/act/newpneumonia/newpneumonia/?from=osari_pc_1'
        response = requests.get(url)
        with open('html.txt','w') as file:
            file.write(response.text)
            print("写入txt成功")

    # 获得更新时间
    def get_time(self):
        with open('html.txt', 'r') as file:
            text = file.read()
        time = re.findall('"mapLastUpdatedTime":"(.*?)"', text)[0]
        return time

    # 解析数据
    def parse_data(self):
        with open('html.txt', 'r') as file:
            text = file.read()
        html = etree.HTML(text)
        result = html.xpath('//script[@type="application/json"]/text()')[0]
        result = json.loads(result)
        result = result['component'][0]['caseList']
        # result['component'][0]获得列表第0项 是一个字典
        # print(result['component'][0]['caseList'])
        # 字典转换为字符串
        result = json.dumps(result)
        with open('data.json', 'w') as file:
            file.write(result)
            print('写入json成功')


# data = Get_data()
# data.get_data()
# data.get_time()
# data.parse_data()

data_more.py

import json
import map_draw
import data_get

with open('data.json', 'r') as file:
    data = file.read()
    data = json.loads(data)
map = map_draw.Draw_map()


# print(data)
# 中国疫情地图数据
def china_map(update_time):
    area = []
    confirmed = []
    for each in data:
        # print(each)
        area.append(each['area'])
        confirmed.append(each['confirmed'])
    map.to_map_china(area, confirmed, update_time)


# 省份疫情地图数据
def province_map(update_time):
    for each in data:
        city = []
        confirmeds = []
        province = each['area']
        # 出现空列表是因为特别行政区
        for each_city in each['subList']:
            city.append(each_city['city'] + "市")
            confirmeds.append(each_city['confirmed'])
            map.to_map_city(city, confirmeds, province, update_time)
        if province == '上海' or '北京' or '天津' or '重庆':
            for each_city in each['subList']:
                city.append(each_city['city'])
                confirmeds.append(each_city['confirmed'])
                map.to_map_city(city, confirmeds, province, update_time)
    print("生成城市疫情地图成功")

map_draw.py

from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.faker import Faker


class Draw_map():
    # 颜色RGB转换 脱离函数,不需要定义self
    def get_color(self,a,b,c):
        result = '#'+''.join(map((lambda x:"%02x" % x),(a,b,c)))
        return result.upper()

    def to_map_city(self, area, variate,province,update_time):
        pieces = [
            {"max": 99999999, "min": 1001, 'label': '>10000', 'color': self.get_color(102,2,8)},
            {"max": 9999, "min": 1000, 'label': '1000-9999', 'color':self.get_color(140,13,13)},
            {"max": 999, "min": 500, 'label': '500-999', 'color':self.get_color(204,41,41)},
            {"max": 499, "min": 100, 'label': '100-999', 'color': self.get_color(255,123,105)},
            {"max": 99, "min": 50, 'label': '50-99', 'color': self.get_color(255,170,133)},
            {"max": 49, "min": 10, 'label': '10-49', 'color':self.get_color(255,202,179)},
            {"max": 9, "min": 1, 'label': '1-9', 'color': self.get_color(255,228,217)},
            {"max": 0, "min": 0, 'label': '0', 'color': self.get_color(255,255,255)},
        ]

        c = (
            # 设置地图大小
            Map(init_opts=opts.InitOpts(width='1000px',height='880px'))
                .add("累计确诊人数", [list(z) for z in zip(area, variate)],province,is_map_symbol_show=False)
                .set_global_opts(
                title_opts=opts.TitleOpts(title="%s地区疫情地图分布"%(province),subtitle='截至%s %s省疫情分布情况'%(update_time,province)
                                          ,pos_left='center',pos_top='30px',),
                legend_opts=opts.LegendOpts(is_show=False),
                visualmap_opts=opts.VisualMapOpts(max_=200, is_piecewise=True, pieces=pieces)
            )
                .render("./map/{}疫情地图.html".format(province))
        )

    def to_map_china(self, area, variate, update_time):
        # 分段
        pieces = [
            {"max": 99999999, "min": 1001, 'label': '>10000', 'color': '#8A0808'},
            {"max": 9999, "min": 1000, 'label': '1000-9999', 'color': '#B40404'},
            {"max": 999, "min": 100, 'label': '100-999', 'color': '#DF0101'},
            {"max": 99, "min": 10, 'label': '1-9', 'color': '#F5A9A9'},
            {"max": 9, "min": 1, 'label': '1-9', 'color': '#F5A9A9'},
            {"max": 0, "min": 0, 'label': '0', 'color': '#FFFFFF'},
        ]
        c = (
            Map(init_opts=opts.InitOpts(width='1000px', height='880px'))
                # zip内置函数,实现数据对应
                .add("累计确诊人数", [list(z) for z in zip(area, variate)], "china")
                .set_global_opts(
                title_opts=opts.TitleOpts(title="中国疫情地图分布", subtitle='截至%s 中国疫情分布情况' % (update_time),
                                          pos_left='center',pos_top='30px'),
                visualmap_opts=opts.VisualMapOpts(max_=200, is_piecewise=True, pieces=pieces),
            )
                .render("中国疫情地图.html")
        )
        print("生成中国疫情地图成功")

main.py

import data_more
import data_get


datas = data_get.Get_data()
# 爬取数据并保存
datas.get_data()
# 更新时间
update_time = datas.get_time()
# 解析数据
datas.parse_data()

# 生成中国疫情地图
data_more.china_map(update_time)
# 生成城市疫情地图
data_more.province_map(update_time)

一个可爱的人